package io.gitee.yxsnake.framework.log.event.listener;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import io.gitee.yxsnake.framework.core.constant.Constants;
import io.gitee.yxsnake.framework.core.utils.ResultUtils;
import io.gitee.yxsnake.framework.core.utils.ServletUtils;
import io.gitee.yxsnake.framework.core.utils.StringUtils;
import io.gitee.yxsnake.framework.core.utils.ip.IpUtil;
import io.gitee.yxsnake.framework.core.utils.login.LoginHelper;
import io.gitee.yxsnake.framework.log.event.LoginEvent;
import io.gitee.yxsnake.framework.log.event.OperatorLogEvent;
import io.gitee.yxsnake.framework.system.api.RemoteClientService;
import io.gitee.yxsnake.framework.system.api.RemoteLogService;
import io.gitee.yxsnake.framework.system.api.domain.bo.RemoteAccessLogBo;
import io.gitee.yxsnake.framework.system.api.domain.bo.RemoteOperatorLogBo;
import io.gitee.yxsnake.framework.system.api.domain.vo.RemoteClientVo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

/**
 * @author snake
 * @description  异步调用日志服务
 * @since 2024/11/3 15:17
 */
@Slf4j
@Component
public class  LogEventListener {

    @Resource
    private RemoteLogService remoteLogService;

    @Resource
    private RemoteClientService remoteClientService;

    public LogEventListener() {
    }

    /**
     * 保存系统日志记录
     */
    @EventListener
    public void saveLog(OperatorLogEvent operatorLogEvent) {
        RemoteOperatorLogBo sysOperatorLog = BeanUtil.toBean(operatorLogEvent, RemoteOperatorLogBo.class);
        remoteLogService.saveLog(sysOperatorLog);
    }

    /**
     * 保存系统访问记录
     */
    @EventListener
    public void saveLoginEventLog(LoginEvent loginEvent) {
        HttpServletRequest request = ServletUtils.getRequest();
        final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
        final String ip = ServletUtils.getClientIp();
        // 客户端信息
        String clientId = request.getHeader(LoginHelper.CLIENT_KEY);
        RemoteClientVo clientVo = null;
        if (StringUtils.isNotBlank(clientId)) {
            clientVo = ResultUtils.getResultData(remoteClientService.queryByClientId(clientId));
        }

        String address = IpUtil.getIpAddr(ServletUtils.getRequest());
        StringBuilder s = new StringBuilder();
        s.append(getBlock(ip));
        s.append(address);
        s.append(getBlock(loginEvent.getUsername()));
        s.append(getBlock(loginEvent.getStatus()));
        s.append(getBlock(loginEvent.getMessage()));
        // 打印信息到日志
        log.info(s.toString(), loginEvent.getArgs());
        // 获取客户端操作系统
        String os = userAgent.getOs().getName();
        // 获取客户端浏览器
        String browser = userAgent.getBrowser().getName();
        // 封装对象
        RemoteAccessLogBo accessLogBo = new RemoteAccessLogBo();
        accessLogBo.setTenantId(loginEvent.getTenantId());
        accessLogBo.setUserName(loginEvent.getUsername());
        if (ObjectUtil.isNotNull(clientVo)) {
            accessLogBo.setClientKey(clientVo.getClientKey());
            accessLogBo.setDeviceType(clientVo.getDeviceType());
        }
        accessLogBo.setIpaddr(ip);
        accessLogBo.setLoginLocation(address);
        accessLogBo.setBrowser(browser);
        accessLogBo.setOs(os);
        accessLogBo.setMsg(loginEvent.getMessage());
        // 日志状态
        if (StringUtils.equalsAny(loginEvent.getStatus(), Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
            accessLogBo.setStatus(Constants.SUCCESS);
        } else if (Constants.LOGIN_FAIL.equals(loginEvent.getStatus())) {
            accessLogBo.setStatus(Constants.FAIL);
        }
        remoteLogService.saveAccessLog(accessLogBo);
    }

    private String getBlock(Object msg) {
        if (msg == null) {
            msg = "";
        }
        return "[" + msg + "]";
    }
}
